package day28;

import com.oracle.net.Sdp;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;

//一级菜单：注册，登录，退出
//二级菜单：聊天（私聊），退出登录（返回上一级）
//登录成功记录缓存，下次可以免登录（缓存一分钟）
//登录成功后进入聊天功能（输入聊天的用户）
public class UserSystem {
    static Scanner sc=new Scanner(System.in);
    static List<User> list=new ArrayList<>();
    static User userLogin;
    static {
        //反序列化，读取集合
    }
    public static void main(String[] args) {
        one();
    }
    public static void one() {
        while (true){
            System.out.println("***XXX用户系统***");
            System.out.println("1.注册");
            System.out.println("2.登录");
            System.out.println("3.退出");
            System.out.println("****************");
            System.out.print("请输入对应的编号:");
            int num=sc.nextInt();
            switch (num){
                case 1:reg();break;
                case 2:login();break;
                case 3:
                    System.out.println("退出系统!");
                    return;
                default:
                    System.out.println("输入错误，请重新输入!");
                    break;
            }
        }
    }

    public static void reg() {
        System.out.print("请输入手机号:");
        String phone=sc.next();
        System.out.print("请输入密码:");
        String password=sc.next();
        list.add(new User(phone,password));
        //序列化保存数据
    }

    public static void login() {
        //如果登录过，可以免登录（进入two）
        System.out.print("请输入手机号:");
        String phone=sc.next();
        System.out.print("请输入密码:");
        String password=sc.next();
        for (User u:list){
            if (phone.equals(u.phone)&&password.equals(u.password)){
                //是否添加缓存 1分钟之内免登录
                userLogin=u;
                two();
                return;
            }
        }
        System.out.println("手机号或密码错误!");
    }

    public static void two(){
        while (true){
            System.out.println("***"+userLogin.phone+"登录成功^-^***");
            System.out.println("1.聊天功能");
            System.out.println("2.退出登录");
            System.out.println(",0.返回上一级");
            System.out.println("********************");
            System.out.print("请输入对应的编号:");
            int n= sc.nextInt();
            switch (n){
                case 1:chat();break;
                case 2:removeCookie();break;
                case 0:return;
                default:
                    System.out.println("输入错误，请重新输入!");
                    break;
            }
        }
    }
    //服务端可客户端
    public static void chat(){ //私聊(发送方和接收方)
        try {
            Socket client=new Socket("localhost",9999);
            //创建客户端线程，负责读取服务端返回的信息
            UserClientThread t=new UserClientThread(client);
            t.start();
            //发送方：userLogin
            System.out.print("请输入对方的手机号:");
            String toPhone=sc.next();
            OutputStream os=client.getOutputStream();
            //第一次向服务端写，告诉它发送方和接受方是谁
            os.write((userLogin.phone+"=>"+toPhone+"\n").getBytes());
            System.out.println("你要向"+toPhone+"发送消息，如果输入esc表示退出!");
            while (true){
                String msg=sc.nextLine();
                if ("esc".equals(msg)){
                    os.write((userLogin.phone+"退出\n").getBytes());
                    t.b=true; //标记客户端线程结束
                    break;
                }else {
                    os.write((userLogin.phone+"说:"+msg+"\n").getBytes());
                }
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        System.out.println("退出聊天!");
    }

    public static void removeCookie() {
        //实现缓存文件的删除
    }
}
class UserServer{  //服务端
    //定义Map key表示手机号，value表示客户端
    static Map<String,Socket> map=new HashMap<>();
    public static void main(String[] args) throws IOException {
        ServerSocket server=new ServerSocket(9999);
        System.out.println("启动服务端成功!");
        while (true){
            Socket client=server.accept();
            //new线程，单独处理每个客户端私聊的功能
            new UserServerThread(client).start();
        }
    }
}
class UserClientThread extends Thread{
    Socket client;
    volatile boolean b;
    public UserClientThread(Socket client){
        this.client=client;
    }

    public void run() {
        try {
            BufferedReader br=new BufferedReader(new InputStreamReader(client.getInputStream()));
            while (true){
                String msg=br.readLine();
                System.out.println(msg);
                if (b) return;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
class UserServerThread extends Thread{
    Socket client;
    public UserServerThread(Socket client){
        this.client=client;
    }
    public void run() {
        try{
            BufferedReader br=new BufferedReader(new InputStreamReader(client.getInputStream()));
            //保存map
            //第一次读取，会获取客户端第一次读写
            String fromAndTo= br.readLine();  //110=>120
            String phones[]=fromAndTo.split("=>");
            UserServer.map.put(phones[0],client);
            //非第一次，读取消息给接收方写入
            while (true){
                String msg=br.readLine();
                //退出 结束当前线程，删除map集合里面的数据
                if (msg.contains("退出")){
                    UserServer.map.remove(phones[0]);
                    return; //结束run() 结束线程
                }
                //正常消息
                if (UserServer.map.containsKey(phones[1])){
                    Socket toSocket=UserServer.map.get(phones[1]);
                    OutputStream os=toSocket.getOutputStream();
                    os.write((msg+"\n").getBytes());
                }else {  //对方不在线，无法发送，给消息的发送方返回一个结果
                    OutputStream os=client.getOutputStream();
                    os.write((phones[1]+"目前不在线\n").getBytes());
                }


            }
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}
class User implements Serializable{
    String phone;
    String password;

    public User(String phone, String password) {
        this.phone = phone;
        this.password = password;
    }
}